package com.legstar.eci.xmi;

import java.util.Map;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamReader;

import com.thoughtworks.xstream.io.xml.QNameMap;
import com.thoughtworks.xstream.io.xml.StaxReader;
import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer;

/**
 * A slight enhancement to the XStream StaxReader to support attributes
 * with namespace prefixes.
 *
 */
public class AttrStaxReader extends StaxReader {

    /** Maps qualified classes to qualified attributes. */
	private Map < String, String > attrToNamespaceUri;
    
    /** Keep a reference on the stream reader because it is needed in getAttribute.*/
    private final XMLStreamReader in;

    /**
	 * @param qnameMap maps a class to a qualified name
	 * @param attrToNamespaceUri maps a field from a class to a namespace URI
     * @param in the Stax reader
	 * @param replacer an XML name beautifier
     */
    public AttrStaxReader(
    		QNameMap qnameMap,
    		Map < String, String > attrToNamespaceUri,
    		XMLStreamReader in,
			XmlFriendlyReplacer replacer) {
		super(qnameMap, in, replacer);
		this.in = in;
		this.attrToNamespaceUri = attrToNamespaceUri;
	}

	/**
	 * @param qnameMap maps a class to a qualified name
	 * @param attrToNamespaceUri maps a field from a class to a namespace URI
     * @param in the Stax reader
	 */
	public AttrStaxReader(
			QNameMap qnameMap,
			Map < String, String > attrToNamespaceUri,
			XMLStreamReader in) {
		super(qnameMap, in);
		this.in = in;
		this.attrToNamespaceUri = attrToNamespaceUri;
	}

    /**
     * This is the main reason this class exists. We give attributes a
     * chance to be qualified, as in xmi:id, with a different namespace
     * than the holding class.
     */
	@Override
	public String getAttribute(String name) {
        QName classQname = in.getName();
        return in.getAttributeValue(getAttributeNamespaceUri(classQname, name), name);
    }
    
    /**
     * Get the namespace URI for an attribute if any 
     * @param classQname the class qualified queue name
     * @param name the attribute local name
     * @return a namespace URI or null if none is found
     */
    protected String getAttributeNamespaceUri(QName classQname, String name) {
    	if (attrToNamespaceUri != null) {
    		String key = classQname.getLocalPart() + "#"+ name;
    		return attrToNamespaceUri.get(key);
    	}
    	return null;
    }

}
